package tinyinventor;

import codeblocks.*;

/**
 * Scope rule which only allows stub blocks with their scope defined to
 * local to be used in the same contexts as their parent. 
 * 
 * @author Morten Tranberg Hansen
 *
 */

public class ScopeRule implements LinkRule {

	@Override
	public boolean canLink(Block block1, Block block2, BlockConnector socket1, BlockConnector socket2) {
	
		// Make sure that variables are not accessed outside of their scope
		String block1Scope = block1.getProperty("scope");
		String block2Scope = block2.getProperty("scope");
		
		boolean block1Local = block1Scope!=null && block1Scope.equals("local") && (block1 instanceof BlockStub);
		boolean block2Local = block2Scope!=null && block2Scope.equals("local") && (block2 instanceof BlockStub);
		
		if(block1Local || block2Local) {
			Block root1 = getRootBlock(block1);
			Block root2 = getRootBlock(block2);
			if(block1Local) {
				Block parentRoot = getRootBlock(((BlockStub)block1).getParent());
				if(parentRoot!=root1 && parentRoot!=root2) {
					return false;
				}
			}
			if(block2Local) {
				Block parentRoot = getRootBlock(((BlockStub)block2).getParent());
				if(parentRoot!=root1 && parentRoot!=root2) {
					return false;
				}
			}
		}
		
		/*
		System.out.println("block1: " + block1.getGenusName() + ", block2: " + block2.getGenusName());
		System.out.println("stub1? " + (block1 instanceof BlockStub) + ", stub?: " + (block2 instanceof BlockStub));
		System.out.println("scope1: " + block1Scope + ", scope2: " + block2Scope);
		System.out.println("root1: " + getRootBlock(block1).getGenusName() + ", root2: " + getRootBlock(block2).getGenusName());
		*/
		
		return true;
	}

	private Block getRootBlock(Block block) {
		if(!BlockLinkChecker.hasPlugEquivalent(block)) {
			return block;
		}
		
		BlockConnector plug = BlockLinkChecker.getPlugEquivalent(block);
		if(!plug.hasBlock()) {
			return block;
		}
		
		return getRootBlock(Block.getBlock(plug.getBlockID()));
	}
	
	
	@Override
	public boolean isMandatory() {
		return true;
	}
	
}
